#include "timer_peripheral.h"
#include "gd32e23x.h"

void Timer16SetFre(uint32_t fre)
{
	uint32_t period;
	uint32_t prescaler;
	uint32_t preFfe;
    uint32_t sysClk = SystemCoreClock / 1000000;
	timer_parameter_struct timerInitpara;
	
	rcu_periph_clock_enable(RCU_TIMER16);
	
	prescaler = sysClk - 1;
	preFfe = SystemCoreClock / (prescaler + 1);
	while ((prescaler > 0) && (prescaler < 65536)) {
		period = preFfe / fre;
		if (period > 65536) {
			prescaler = sysClk * 2 - 1;
			preFfe = SystemCoreClock / (prescaler + 1);
		}
		else if (preFfe / fre == 0) {
			prescaler = sysClk / 2 - 1;
			preFfe = SystemCoreClock / (prescaler + 1);
		}
		else {
			break;
		}
	}
	
	timer_deinit(TIMER16);
	timerInitpara.alignedmode = TIMER_COUNTER_EDGE;
	timerInitpara.clockdivision = TIMER_CKDIV_DIV1;
	timerInitpara.counterdirection = TIMER_COUNTER_UP;
	timerInitpara.period = period;
	timerInitpara.prescaler = prescaler;
	timerInitpara.repetitioncounter = 0;
	timer_init(TIMER16, &timerInitpara);
	
	nvic_irq_enable(TIMER16_IRQn, 12);
	timer_interrupt_enable(TIMER16, TIMER_INT_UP);
}

void Timer16Run(void)
{
	timer_enable(TIMER16);
}

void Timer16Stop(void)
{
	timer_disable(TIMER16);
}
